import concurrent.futures
import os
import threading

import pydicom
from pathlib import Path

from dicom_viewer_be_mock_xiaosai.service.api_middleware import logger
from src.dicom_viewer_be_mock_xiaosai.loader.DicomLoader import DicomLoader


def process_dicom_file(filepath):
    try:
        p = Path(filepath)
        folder_path = str(p.parent)
        filename = p.name
        ds = pydicom.dcmread(filepath, force=True)
        patient_name = getattr(ds, 'PatientName', 'Unknown')
        if patient_name == '':
            patient_name = 'Unknown'

        # 将PatientName对象转换为字符串
        if not isinstance(patient_name, str):
            patient_name = str(patient_name)

        # 获取其他可能有用的信息
        patient_id = getattr(ds, 'PatientID', 'Unknown')
        study_date = getattr(ds, 'StudyDate', 'Unknown')
        series_uid = getattr(ds, 'SeriesInstanceUID', 'Unknown')
        series_description = getattr(ds, 'SeriesDescription', 'Unknown')
        desc = "无描述" if ( not series_description or series_description.strip() == '') else series_description
        # uid主要是来区分同一个patient_id 但是patient_name不一样的情况。
        return {
            'patient_uid':f'{patient_id}-{patient_name}',
            'filename': filename,
            'patient_name': patient_name,
            'patient_id': patient_id,
            'study_date': study_date,
            'series_id': series_uid,
            'series_desc':desc,
            "ds":ds,
            "folder_path": folder_path
        }
    except Exception as e:
        logger.critical(f"处理文件 {filepath} 时出错: {e}")
        return None


def analyze_dicom_folder(folder_path):
    logger.info(f"正在扫描文件夹: {folder_path}")
    all_files = []
    for root, _, files in os.walk(folder_path):
        for file in files:
            filepath = os.path.join(root, file)
            all_files.append(filepath)
    logger.info(f"找到 {len(all_files)} 个文件，正在处理...")
    # 使用多线程处理DICOM文件
    with concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count()) as executor:
        results = list(executor.map(process_dicom_file, all_files))
    logger.info(f"分配多线程处理dicom文件完成。")
    patient_record_dict = dict()
    series_record_dict = dict()

    dicom_files = [result for result in results if result is not None]
    ds_arr = [result.get('ds') for result in results]
    for each_record in dicom_files:
        _save_patient_record(patient_record_dict, each_record)
        _save_series_record(series_record_dict, each_record)
        DicomLoader.save_filename_dict(each_record)
    return patient_record_dict, series_record_dict,ds_arr





def _save_patient_record(patient_record_dict,each_record):
    patient_name = each_record['patient_name']
    patient_uid = each_record['patient_uid']
    series_id = each_record['series_id']
    patient_info = patient_record_dict.get(patient_uid, {
        "patientName": patient_name,
        "seriesIds": []
    })
    if patient_info["seriesIds"].__contains__(series_id) is False:
        patient_info["seriesIds"].append(series_id)
    patient_record_dict[patient_uid] = patient_info


def _save_series_record(series_record_dict, each_record):
    patient_name = each_record['patient_name']
    patient_id = each_record['patient_id']
    series_id = each_record['series_id']
    series_desc = each_record['series_desc']
    folder_path = each_record['folder_path']
    series_info = series_record_dict.get(series_id, {
        "count": 0,
        "desc": series_desc,
        "thumbnail": "",
        "patientName": patient_name,
        "patientId": patient_id,
        "folderPath":folder_path
    })
    series_info["count"] = series_info["count"] + 1
    series_record_dict[series_id] = series_info


def convert_windows_path_to_container_path(windows_path):
    """将Windows路径转换为容器内路径"""

    # 定义路径映射规则
    path_mappings = {
        r'D:\\test\\': '/app/data',
        r'D:/test/': '/app/data',
        # 可以添加更多映射规则
    }

    # 标准化路径分隔符
    normalized_path = windows_path.replace('\\', '/')

    # 查找匹配的映射
    for windows_prefix, container_prefix in path_mappings.items():
        windows_prefix_normalized = windows_prefix.replace('\\', '/')
        if normalized_path.startswith(windows_prefix_normalized):
            # 替换路径前缀
            relative_path = normalized_path[len(windows_prefix_normalized):].lstrip('/')
            container_path = os.path.join(container_prefix, relative_path)
            return container_path

    # 如果没有匹配的映射，返回原路径（可能会导致错误）
    return windows_path